package com.hmall.order.listener;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hmall.feign.client.ItemClient;
import com.hmall.order.Constants.OrderConstants;
import com.hmall.order.Constants.RabbitConstants;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Objects;

/**
 * @author Lewis
 * @date 2023/4/10 10:25
 * description  消息监听
 */

//@Component
@Slf4j
public class SpringRabbitListener {


    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private ItemClient itemClient;

    /**
     * 声明DelayExchange交换机,处理延迟消息
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = RabbitConstants.DELAY_QUEUE, durable = "true"),
            exchange = @Exchange(name = RabbitConstants.EXCHANGE, delayed = "true"),
            key = RabbitConstants.ROUTING_KEY
    ))
    public void listenDelayQueue(String msg) {
        log.info("接收到的延迟消息：{}", msg);

        // 0-存在性校验
        if (Objects.isNull(msg)) {
            throw new RuntimeException("消息不存在");
        }
        // 1-根据orderId查询订单
        Long orderId = Long.valueOf(msg);
        Order order = orderMapper.selectById(orderId);
        // 1.2存在性校验
        if (Objects.isNull(order)) {
            throw new RuntimeException("订单不存在");
        }
        // 2-判断订单status是否为1
        if (!Objects.equals(1, order.getStatus())) {
            return;
        }
        // 3-为1则继续 根据orderId查询订单详情，得到商品购买数量
        LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderDetail::getOrderId, orderId);
        OrderDetail orderDetail = orderDetailMapper.selectOne(wrapper);
        // 3.1 存在性校验
        if (Objects.isNull(orderDetail)) {
            throw new RuntimeException("订单详情不存在！");
        }
        Integer num = orderDetail.getNum();
        // 4-根据orderId修改订单status为5（取消），注意幂等判断，避免重复消息
        // 4.1 幂等判断 如果商品状态已经为 5 已取消
        if (Objects.equals(OrderConstants.CANCELED, order.getStatus())) {
            return;
        }
        order.setStatus(OrderConstants.CANCELED);
        // 4.2 设置取消时间 更新时间
        order.setCloseTime(DateTime.now());
        order.setUpdateTime(DateTime.now());
        orderMapper.updateById(order);
        // 5-调用item-service，根据商品id、商品数量恢复库存
        log.info("开始恢复库存：{}", order);
        itemClient.deductStock(orderDetail.getItemId(), num);


    }
}
